import redis
from rest_framework.views import APIView
from rest_framework.response import Response

from users.models import User
from goods.models import Goods


class AddCart(APIView):
    """
    添加购物车
    """
    def post(self, request):
        """
        1.获取前端传来的username 和商品id
        2. 分别根据用户名获取用户对象,根据商品id获取商品对象
        3. 链接redis,准别写入数据库
            1. 判断商品之前是否在redis中存在;
                1. 若存在,要计算出之前商品的总数量, 当前的总量+商品的数量是否大于库存数量
                    1. 大于库存, 不能购买”code“:202, "msg":"加购达到限购数量！"
                    2. 小于库存, 购买, 把之前的额商品数量+1
                2. 该商品的库存为空, 不能添加到购物车
            2. 在redis中不存在,第一次加入购物车, 直接写入,hash set
            3. 其他错误
        """
        # 1.获取前端传来的username 和商品id
        user_name = request.data.get('user')
        pid = request.data.get('productID')
        # 2.据用户名获取用户对象,根据商品id获取商品对象
        try:
            user = User.objects.get(username=user_name)
        except Exception as e:
            return Response({'msg': "用户不存在", "code": 204})
        try:
            good = Goods.objects.get(id=pid)
        except Exception as e:
            return Response({'msg': "此商品不存在", "code": 400})
        # 3. redis,准别写入数据库
        rdb = redis.Redis(host="localhost", port=6379, password=123)
        # 构建hash的key
        cart_key = "cart_%s" % user.id  # hash 中的key
        cart_selected = "cart_selected_%s" % user.id  # 集合中的key

        # 默认的额商品数量
        count = 1
        # 1. 判断商品的库存
        if good.stock > 0:
            # 有库存的条件判断
            # 1. 判断此商品在redis中是否存在
            num = rdb.hget(cart_key, good.id)
            if num:
                # 此时说明此商品在在购物车中
                # 1. 购物车种次商品的总数量是否大于库存
                # 获取购物车中此商品的总数量,但是从redis中取出的数据是byte类型要转码,然后转换数据类型
                good_count = int(num.decode())
                good_count += count  # 新加的购物车后商品的总数量
                # 此时要吧good_count和商品的额库存对比, 若大于商品的库存,就不能添加购物车
                if good_count > good.stock:
                    rdb.close()
                    return Response({'msg': '已经超出限购数量', "code": 202})
                if good_count <= good.stock:
                    # 此时商品的数量没有超过库存量,把商品的数量+1, 可以写入redis
                    rdb.hset(cart_key, good.id, good_count)  # 写入的是hash
                    rdb.sadd(cart_selected, good.id)
                    # 断开redis
                    rdb.close()
                    return Response({'msg': "商品已存在,数量+1", "code": 201})
            else:
                # 此商品没在购物车,可以直接添加到购物车中
                rdb.hset(cart_key, good.id, count)  # 写入hash
                rdb.sadd(cart_selected, good.id)
                rdb.close()
                # 把添加到购物车中的商品返回
                shopping_cart_data = {
                    "id": cart_key,
                    "productID": good.id,
                    "productName": good.sku_name,
                    "productImg": good.img,
                    "price": good.selling_price,
                    "num": count,  # 该商品在购物车中的数量
                    "maxNum": good.stock,  # 限购数量
                    "check": True,  # 加购，默认是勾选状态
                }
                return Response({'msg': "添加购物车成功", "code": 200, "shoppingCart":shopping_cart_data})

        else:
            return Response({"code": 203, "msg": "库存不足，无法购买！"})
